// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CommonUserWidget.h"
#include "LyraSimulatedInputWidget.generated.h"

#define UE_API LYRAGAME_API

class UEnhancedInputLocalPlayerSubsystem;
class UInputAction;
class UCommonHardwareVisibilityBorder;
class UEnhancedPlayerInput;

/**
 *  一个UMG控件，具有基础功能来向增强输入子系统注入输入（按键或输入动作）。
 */
UCLASS(MinimalAPI, meta=( DisplayName="Lyra Simulated Input Widget" ))
class ULyraSimulatedInputWidget : public UCommonUserWidget
{
	GENERATED_BODY()
	
public:
	
	UE_API ULyraSimulatedInputWidget(const FObjectInitializer& ObjectInitializer); // 构造函数
	
	//~ Begin UWidget
#if WITH_EDITOR
	/**
	 * 获取调色板类别
	 * @return 调色板类别文本
	 */
	UE_API virtual const FText GetPaletteCategory() override;
#endif
	//~ End UWidget interface

	//~ Begin UUserWidget
	/**
	 * 原生构造
	 */
	UE_API virtual void NativeConstruct() override;
	/**
	 * 原生析构
	 */
	UE_API virtual void NativeDestruct() override;
	/**
	 * 触摸结束时的原生处理
	 * @param InGeometry 几何信息
	 * @param InGestureEvent 手势事件
	 * @return 回复
	 */
	UE_API virtual FReply NativeOnTouchEnded(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent) override;
	//~ End UUserWidget interface
	
	/** 根据此控件的所属本地玩家获取增强输入子系统。如果没有所属玩家则返回null */
	UFUNCTION(BlueprintCallable)
	UE_API UEnhancedInputLocalPlayerSubsystem* GetEnhancedInputSubsystem() const;

	/** 从当前输入子系统获取当前玩家输入 */
	UE_API UEnhancedPlayerInput* GetPlayerInput() const;

	/** 获取关联的输入动作 */
	UFUNCTION(BlueprintCallable)
	const UInputAction* GetAssociatedAction() const { return AssociatedAction; }

	/** 返回将用于输入任何值的当前键。 */
	UFUNCTION(BlueprintCallable)
	FKey GetSimulatedKey() const { return KeyToSimulate; }

	/**
	 * 将给定的向量作为输入注入到当前模拟键。
	 * 这会在当前玩家上调用"InputKey"。
	 */
	UFUNCTION(BlueprintCallable)
	UE_API void InputKeyValue(const FVector& Value);

	/**
	 * 将给定的向量作为输入注入到当前模拟键。
	 * 这会在当前玩家上调用"InputKey"。
	 */
	UFUNCTION(BlueprintCallable)
	UE_API void InputKeyValue2D(const FVector2D& Value);

	/**
	 * 刷新模拟输入
	 */
	UFUNCTION(BlueprintCallable)
	UE_API void FlushSimulatedInput();
	
protected:

	/** 根据从增强输入查询关于哪些键映射到关联动作的信息来设置 KeyToSimulate */
	UE_API void QueryKeyToSimulate();

	/** 当控制映射改变时调用，这样我们有机会调整我们自己的键 */
	UFUNCTION()
	UE_API void OnControlMappingsRebuilt();

	/** 通用可见性边框将允许你为特定平台指定UI（如果需要） */
	UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) // 通用可见性边框
	TObjectPtr<UCommonHardwareVisibilityBorder> CommonVisibilityBorder = nullptr;
	
	/** 我们应该模拟输入的关联输入动作 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly) // 关联的输入动作
	TObjectPtr<const UInputAction> AssociatedAction = nullptr;

	/** 在当前没有键绑定到关联动作的情况下，用于模拟输入的键 */
	UPROPERTY(BlueprintReadOnly, EditAnywhere) // 回退绑定键
	FKey FallbackBindingKey = EKeys::Gamepad_Right2D;

	/** 应该通过玩家输入上的InputKey输入的键 */
	FKey KeyToSimulate; // 要模拟的键
};

#undef UE_API